/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.nanosn.coffeemaker.server.restlet;

import com.nanosn.coffeemaker.server.urls.Pattern;
import com.nanosn.coffeemaker.server.urls.Patterns;
import com.nanosn.coffeemaker.server.urls.UrlBase;
import freemarker.template.Configuration;
import java.io.File;
import java.io.IOException;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.restlet.Application;
import org.restlet.Restlet;
//import org.restlet.ext.jaxrs.JaxRsApplication;
import org.restlet.resource.Directory;
import org.restlet.routing.Router;

/**
 *
 * @author selkhateeb
 */
public class CoffeeMakerApplication extends Application {

    private Configuration configuration = new Configuration();
    private ClassLoader classLoader;

    public CoffeeMakerApplication(ClassLoader cl) {
        this.setClassLoader(cl);
        try {
            //TODO: Need to point at the classes directory or maybe not
            configuration.setDirectoryForTemplateLoading(new File("."));
        }
        catch (IOException ex) {
            Logger.getLogger(CoffeeMakerApplication.class.getName()).log(
                    Level.SEVERE, null, ex);
        }
    }

    /**
     * Creates a root Restlet that will receive all incoming calls.
     */
    @Override
    public synchronized Restlet createRoot() {


        Map m = getContext().getAttributes();
        //TODO : remove debugging info
        System.out.println("REAL PATH :" + m.containsKey("RealPath"));
        System.out.println("REAL PATH :" + m.get("RealPath"));



        Router router = new Router(getContext());
        // Defines only one route which is the root
        //TODO: maybe I need to attach something else to handle static files
        //      see in the working project directory .. I think in the
        //      NanosnWebFramework i was trying to do something similer

        UrlBase urls = null;
        try {
            urls = getUrls();
        }
        catch (Exception ex) {
            Logger.getLogger(CoffeeMakerApplication.class.getName()).log(
                    Level.SEVERE, null, ex);
        }
        Patterns patterns = urls.getUrlpatterns();
        for (Pattern pattern : patterns.getPatterns()) {
            if (pattern.getDirectory() != null) {
                //TODO use REAL PATH as an alternative for relative path
                
                String path = "file://" + pattern.getDirectory().getDirectory();
                router.attach(pattern.getUriTemplate(), new Directory(this.
                        getContext().createChildContext(), path));
                continue;
            }
            Class c = null;
            try {
                c = getClassLoader().loadClass(pattern.getClassName());
                //TODO: need to do some error checking on c to make sure it extends the CoffeeMakerResource
                if (c.getSuperclass().equals(Application.class)) {
                    try {
                        //Create an instance
                        Application application =
                                (Application) c.newInstance();
                        application.setContext(this.getContext().createChildContext());

                        //Attach it
                        router.attach(pattern.getUriTemplate(), application);
                    }
                    catch (InstantiationException ex) {
                        Logger.getLogger(CoffeeMakerApplication.class.getName()).
                                log(Level.SEVERE, null, ex);
                    }
                    catch (IllegalAccessException ex) {
                        Logger.getLogger(CoffeeMakerApplication.class.getName()).
                                log(Level.SEVERE, null, ex);
                    }
                }
                else {
                    router.attach(pattern.getUriTemplate(), c);
                }
            }
            catch (ClassNotFoundException ex) {
                Logger.getLogger(CoffeeMakerApplication.class.getName()).log(
                        Level.SEVERE, null, ex);
            }

        }
        return router;
    }

    public Configuration getFreemarkerConfiguration() {
        return configuration;
    }

    private void setClassLoader(ClassLoader cl) {
        this.classLoader = cl;
    }

    public ClassLoader getClassLoader() {
        return classLoader;
    }

    private UrlBase getUrls() throws Exception {
        String rootPackage = (String) getContext().getAttributes().get(
                "ProjectName");

        String className = rootPackage + ".Urls";

        Class urlClass;
        try {
            urlClass = this.getClass().getClassLoader().loadClass(className);
        }
        catch (ClassNotFoundException ex) {
            urlClass = getClassLoader().loadClass(className);

        }
        System.out.println("urlClass = " + urlClass);
        return (UrlBase) urlClass.newInstance();
    }
}
